import os.path
import socket
import io
import os
import json
import threading

localIP='192.168.56.104'
buffer_size=1024
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.bind((localIP,8080))
sock.listen()
print('Port 8080 is ready to listen...')

class myThread(threading.Thread):
    def __init__(self,path,conn,size):
        threading.Thread.__init__(self)
        self.path=path
        self.size=size
        self.conn=conn

    def run(self):
        file=open(path,'rb')
        while file.tell()<self.size:
            self.conn.send(file.read(buffer_size))
        file.close()
        self.conn.close()
        print('Transfer complete')

while True:
    conn,address=sock.accept()
    #conn.connect(address)
    recv=conn.recv(buffer_size).decode()
    request=json.loads(recv)
    print(type(request))
    print('Message from {0} : {1}'.format(address,recv))

    if not request['request-type']:#request for file

        path=request['request-body']['path']
        
        if not os.path.exists(path):
            response=json.dumps({'status code':'404'}).encode()
            conn.send(response)
            continue
        
        size=os.path.getsize(path)
        response=json.dumps({'status code':200,'content-length':size}).encode()
        conn.send(response)

        print('Now start to transfer file to {}'.format(address))
        
    #     file=open(path,'rb')
    #     while file.tell()<size:
    #         conn.send(file.read(buffer_size))
    #     file.close()
    # conn.close()
        thread=myThread(path,conn,size)
        thread.start()

    else:
        dest=request['request-body']['address']
        message=request['request-body']['message']
        print(type(dest))

        message_sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        message_sock.connect((dest,6666))
        message_body={'source':address,'message':message}
        message_body=json.dumps(message_body).encode()
        message_sock.send(message_body)
        print('Message sent!')
        message_sock.close()

sock.close()